Completed
Pull Request — master (#150)
by
unknown
01:06
created

CODE128.js ➔ ... ➔ ???   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 1
rs 10
c 0
b 0
f 0
1
import Barcode from "../Barcode.js";
2
import { SHIFT, SET_A, SET_B, MODULO, STOP, ABC, SWAP, BARS } from './constants';
3
4
// This is the master class,
5
// it does require the start code to be included in the string
6
class CODE128 extends Barcode {
7
	constructor(data, options) {
8
		super(data.substring(1), options);
9
10
		// Get array of ascii codes from data
11
		this.bytes = data.split('')
12
			.map(char => char.charCodeAt(0));
13
	}
14
15
	valid() {
16
		// ASCII value ranges 0-127, 200-211
17
		return /^[\x00-\x7F\xC8-\xD3]+$/.test(this.data);
18
	}
19
20
	// The public encoding function
21
	encode() {
22
		const bytes = this.bytes;
23
		// Remove the start code from the bytes and set its index
24
		const startIndex = bytes.shift() - 105;
25
		// Get start set by index
26
		const startSet = ABC[startIndex];
27
28
		if (startSet === undefined) {
29
			throw new RangeError('The encoding does not start with a start character.');
30
		}
31
32
		// Start encode with the right type
33
		const encodingResult = CODE128.next(bytes, 1, startSet);
34
35
		return {
36
			text:
37
				this.text === this.data
38
					? this.text.replace(/[^\x20-\x7E]/g, '')
39
					: this.text,
40
			data:
41
				// Add the start bits
42
				CODE128.getBar(startIndex) +
43
				// Add the encoded bits
44
				encodingResult.result +
45
				// Add the checksum
46
				CODE128.getBar((encodingResult.checksum + startIndex) % MODULO) +
47
				// Add the end bits
48
				CODE128.getBar(STOP)
49
		};
50
	}
51
52
	// Get a bar symbol by index
53
	static getBar(index) {
54
		return BARS[index] ? BARS[index].toString() : '';
55
	}
56
57
	// Correct an index by a set and shift it from the bytes array
58
	static correctIndex(bytes, set) {
59
		if (set === SET_A) {
60
			const charCode = bytes.shift();
61
			return charCode < 32 ? charCode + 64 : charCode - 32;
62
		} else if (set === SET_B) {
63
			return bytes.shift() - 32;
64
		} else {
65
			return (bytes.shift() - 48) * 10 + bytes.shift() - 48;
66
		}
67
	}
68
69
	static next(bytes, pos, set) {
70
		if (!bytes.length) return { result: '', checksum: 0 };
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
71
		let nextCode, index;
72
73
		// Special characters
74
		if (bytes[0] >= 200){
75
			index = bytes.shift() - 105;
76
			const nextSet = SWAP[index];
77
78
			// Swap to other set
79
			if (nextSet !== undefined) {
80
				nextCode = CODE128.next(bytes, pos + 1, nextSet);
81
			}
82
			// Continue on current set but encode a special character
83
			else {
84
				// Shift
85
				if ((set === SET_A || set === SET_B) && index === SHIFT) {
86
					// Convert the next character so that is encoded correctly
87
					bytes[0] = (set === SET_A)
88
						? bytes[0] > 95 ? bytes[0] - 96 : bytes[0]
89
						: bytes[0] < 32 ? bytes[0] + 96 : bytes[0];
90
				}
91
				nextCode = CODE128.next(bytes, pos + 1, set);
92
			}
93
		}
94
		// Continue encoding
95
		else {
96
			index = CODE128.correctIndex(bytes, set);
97
			nextCode = CODE128.next(bytes, pos + 1, set);
98
		}
99
100
		// Get the correct binary encoding and calculate the weight
101
		const enc = CODE128.getBar(index);
102
		const weight = index * pos;
103
104
		return {
105
			result: enc + nextCode.result,
106
			checksum: weight + nextCode.checksum
107
		};
108
	}
109
}
110
111
export default CODE128;
112